#!/bin/sh
# shellcheck shell=dash disable=SC2169,SC3010,SC3015 source=/dev/null
#
# Startup script to identify and setup RTC clocks
#

# initialize a potentially existing RTC clock
init_rtc_device() {

  # load the i2c_dev module if this is not a virtual
  # applicance but a real rpi/tinkerboard
  if [[ ! "${HM_HOST}" =~ oci\|ova-\|nuc\|generic-\|lxc ]]; then
    modprobe i2c_dev
  fi

  if { [[ -e /sys/module/rtc_ds1307/drivers/i2c:rtc-ds1307/1-0032/name ]] &&
       [[ $(cat /sys/module/rtc_ds1307/drivers/i2c:rtc-ds1307/1-0032/name) == "rx8130" ]]; } ||
     { [[ -e /sys/module/rtc_rx8130/drivers/i2c:rtc-rx8130/1-0032/name ]] &&
       [[ $(cat /sys/module/rtc_rx8130/drivers/i2c:rtc-rx8130/1-0032/name) == "rx8130-legacy" ]]; }; then
    HM_RTC="rx8130"

    # we found a RX8130, thus we assume the RPI-RF-MOD to
    # be present, thus we setup the LED GPIOs

    # check if the HOST is a oci or lxc host and if so make sure
    # to load the rpi_rf_mod_led kernel module early if not present already
    if [[ "${HM_HOST}" =~ oci\|lxc ]] &&
       [[ ! -e /sys/class/leds/rpi_rf_mod:green/trigger ]] &&
       ! grep -Eq "^rpi_rf_mod_led " /proc/modules; then

      # retrieve pin numbers from raw-uart kernel device
      if [[ -e /sys/class/raw-uart/raw-uart/red_gpio_pin ]]; then
        RED_PIN=$(cat /sys/class/raw-uart/raw-uart/red_gpio_pin)
        GREEN_PIN=$(cat /sys/class/raw-uart/raw-uart/green_gpio_pin)
        BLUE_PIN=$(cat /sys/class/raw-uart/raw-uart/blue_gpio_pin)

        # load rpi_rf_mod_led with retrieved led gpio pins
        modprobe -q rpi_rf_mod_led red_gpio_pin="${RED_PIN}" green_gpio_pin="${GREEN_PIN}" blue_gpio_pin="${BLUE_PIN}"
      else
        echo -n "WARN: no RPI-RF-MOD led pin info, "
      fi
    fi

    # show a constant yellow light
    if [[ -e /sys/class/leds/rpi_rf_mod:green/trigger ]]; then
      echo default-on >/sys/class/leds/rpi_rf_mod:green/trigger
      echo default-on >/sys/class/leds/rpi_rf_mod:red/trigger
      echo none >/sys/class/leds/rpi_rf_mod:blue/trigger
    fi

    # in addition, we load the dummy_rx8130 kernel module so
    # that the hss_led process assumes a RPI-RF-MOD is present
    if ! grep -Eq "_rx8130 " /proc/modules; then
      modprobe dummy_rx8130
    fi

    return 1
  fi

  # make sure we load the RTC kernel module for
  # the tinkerboard
  if [[ "${HM_HOST}" == "tinkerboard" ]]; then
    modprobe rtc_rk808
  fi

  # only continue if we don't have a valid rtc yet or otherwise
  # this must be an onboard RTC (e.g. tinkerboard)
  [[ -c /dev/rtc0 ]] && return 0

  # check for MCP7940N RTC clock at 0x6f (PiFace Shim RTC)
  if i2cget -y 1 0x6f 0x00 2>/dev/null >/dev/null; then
    # calibrate MCP7940N
    if i2cset -y 1 0x6f 0x08 0x47 2>/dev/null >/dev/null; then
      if modprobe i2c:mcp7941x; then
        [[ -c /dev/rtc0 ]] && return 0
        echo mcp7941x 0x6f >/sys/class/i2c-dev/i2c-1/device/new_device
        [[ -c /dev/rtc0 ]] && return 0
        echo 0x6f >/sys/class/i2c-dev/i2c-1/device/delete_device
      fi
    fi
  fi

  # check for DS3231/DS1307 RTC clock at 0x68
  if i2cget -y 1 0x68 0x00 2>/dev/null >/dev/null; then
    # check for DS3231
    modprobe i2c:ds3231
    if modprobe i2c:ds3231; then
      [[ -c /dev/rtc0 ]] && return 0
      echo ds3231 0x68 >/sys/class/i2c-dev/i2c-1/device/new_device
      [[ -c /dev/rtc0 ]] && return 0
      echo 0x68 >/sys/class/i2c-dev/i2c-1/device/delete_device
    fi

    # check for DS1307
    if modprobe i2c:ds1307; then
      [[ -c /dev/rtc0 ]] && return 0
      echo ds1307 0x68 >/sys/class/i2c-dev/i2c-1/device/new_device
      [[ -c /dev/rtc0 ]] && return 0
      echo 0x68 >/sys/class/i2c-dev/i2c-1/device/delete_device
    fi
  fi

  # check for PCF8563 RTC clock at 0x51
  if i2cget -y 1 0x51 0x00 2>/dev/null >/dev/null; then
    # check for PCF8563
    if modprobe i2c:pcf8563; then
      [[ -c /dev/rtc0 ]] && return 0
      echo pcf8563 0x51 >/sys/class/i2c-dev/i2c-1/device/new_device
      [[ -c /dev/rtc0 ]] && return 0
      echo 0x51 >/sys/class/i2c-dev/i2c-1/device/delete_device
    fi
  fi

  HM_RTC=""
  return 1
}

start() {
  echo -n "Initializing RTC Clock: "

  # source all data from /var/hm_mode
  [[ -r /var/hm_mode ]] && . /var/hm_mode

  # run init RTC method and set RTC name
  # if functions runs throw
  if init_rtc_device; then
    if [[ -e /sys/class/rtc/rtc0/device/name ]]; then
      HM_RTC=$(cat /sys/class/rtc/rtc0/device/name)
    elif [[ -e /sys/class/rtc/rtc0/name ]]; then
      HM_RTC=$(cat /sys/class/rtc/rtc0/name)
    fi
  fi

  # save all HM_ env variables
  set | grep '^HM_' >/var/hm_mode

  if [[ -n "${HM_RTC}" ]]; then
    echo "${HM_RTC}, OK"
  else
    echo "no hardware found"
  fi
}

stop() {
  echo -n "Cleaning up RTC Clock: "

  # source all data from /var/hm_mode
  [[ -r /var/hm_mode ]] && . /var/hm_mode

  # make sure to unload rpi_rf_mod_led which
  # is necessary for docker/lxc-based environments
  if [[ "${HM_HOST}" =~ oci\|lxc ]] &&
     [[ -e /sys/class/leds/rpi_rf_mod:green/trigger ]] &&
     grep -Eq "^rpi_rf_mod_led " /proc/modules; then
    rmmod rpi_rf_mod_led 2>/dev/null
  fi

  echo "OK"
}

restart() {
  stop
  start
}

case "$1" in
  start)
    start
  ;;
  stop)
    stop
  ;;
  restart|reload)
    restart
  ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac

exit 0
